<?php


namespace app\api\unionpay\ysf;

class ClientResponseHandler
{
	public $key;
	public $public_rsa_key;
	public $signtype;
	public $parameters;
	public $debugInfo;
	public $content;
	public function __construct()
	{
		$this->ClientResponseHandler();
	}
	public function ClientResponseHandler()
	{
		$this->key = "";
		$this->public_rsa_key = "";
		$this->signtype = "";
		$this->parameters = [];
		$this->debugInfo = "";
		$this->content = "";
	}
	public function getKey()
	{
		return $this->key;
	}
	public function setKey($key)
	{
		$this->key = $key;
	}
	public function setRSAKey($key)
	{
		$this->public_rsa_key = $key;
	}
	public function setSignType($type)
	{
		$this->signtype = $type;
	}
	public function setContent($content)
	{
		$this->content = $content;
		libxml_disable_entity_loader(true);
		$xml = simplexml_load_string($this->content);
		$encode = $this->getXmlEncode($this->content);
		if ($xml && $xml->children()) {
			foreach ($xml->children() as $node) {
				if ($node->children()) {
					$k = $node->getName();
					$nodeXml = $node->asXML();
					$v = substr($nodeXml, strlen($k) + 2, strlen($nodeXml) - 2 * strlen($k) - 5);
				} else {
					$k = $node->getName();
					$v = \strval($node);
				}
				if ($encode != "" && $encode != "UTF-8") {
					$k = iconv("UTF-8", $encode, $k);
					$v = iconv("UTF-8", $encode, $v);
				}
				$this->setParameter($k, $v);
			}
		}
	}
	public function getContent()
	{
		return $this->content;
	}
	public function getParameter($parameter)
	{
		return isset($this->parameters[$parameter]) ? $this->parameters[$parameter] : "";
	}
	public function setParameter($parameter, $parameterValue)
	{
		$this->parameters[$parameter] = $parameterValue;
	}
	public function getAllParameters()
	{
		return $this->parameters;
	}
	public function isTenpaySign()
	{
		$swiftpassSign = strtolower($this->getParameter("sign"));
		if ($this->getParameter("sign_type") == "MD5") {
			return $this->getMD5Sign() == $swiftpassSign;
		} else {
			if ($this->getParameter("sign_type") == "RSA_1_1" || $this->getParameter("sign_type") == "RSA_1_256") {
				return $this->verifyRSASign();
			}
		}
	}
	public function getMD5Sign()
	{
		$signPars = "";
		ksort($this->parameters);
		foreach ($this->parameters as $k => $v) {
			if ("sign" != $k && "" != $v) {
				$signPars .= $k . "=" . $v . "&";
			}
		}
		$signPars .= "key=" . $this->getKey();
		return strtolower(md5($signPars));
	}
	public function verifyRSASign()
	{
		$signPars = "";
		ksort($this->parameters);
		foreach ($this->parameters as $k => $v) {
			if ("sign" != $k && "" != $v) {
				$signPars .= $k . "=" . $v . "&";
			}
		}
		$signPars = substr($signPars, 0, strlen($signPars) - 1);
		$res = openssl_get_publickey($this->public_rsa_key);
		if ($this->getParameter("sign_type") == "RSA_1_1") {
			$result = \boolval(openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res));
			openssl_free_key($res);
			return $result;
		} elseif ($this->getParameter("sign_type") == "RSA_1_256") {
			$result = \boolval(openssl_verify($signPars, base64_decode($this->getParameter("sign")), $res, OPENSSL_ALGO_SHA256));
			openssl_free_key($res);
			return $result;
		}
	}
	public function getDebugInfo()
	{
		return $this->debugInfo;
	}
	public function getXmlEncode($xml)
	{
		$ret = preg_match("/<?xml[^>]* encoding=\"(.*)\"[^>]* ?>/i", $xml, $arr);
		if ($ret) {
			return strtoupper($arr[1]);
		} else {
			return "";
		}
	}
	public function _setDebugInfo($debugInfo)
	{
		$this->debugInfo = $debugInfo;
	}
	public function _isTenpaySign($signParameterArray)
	{
		$signPars = "";
		foreach ($signParameterArray as $k) {
			$v = $this->getParameter($k);
			if ("sign" != $k && "" != $v) {
				$signPars .= $k . "=" . $v . "&";
			}
		}
		$signPars .= "key=" . $this->getKey();
		$sign = strtolower(md5($signPars));
		$tenpaySign = strtolower($this->getParameter("sign"));
		$this->_setDebugInfo($signPars . " => sign:" . $sign . " tenpaySign:" . $this->getParameter("sign"));
		return $sign == $tenpaySign;
	}
}